//! # 智能告警系统
//!
//! 提供基于指标的自动告警、告警收敛降噪和多种通知方式

use crate::{MetricFamily, Metric, MetricValue, Labels};
use rustcloud_core::{ServiceResult, ServiceError};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, BTreeMap};
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::{RwLock, mpsc};
use async_trait::async_trait;
use tracing::{debug, info, warn, error};
use uuid::Uuid;

/// 告警规则配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlertRule {
    /// 规则ID
    pub id: String,
    /// 规则名称
    pub name: String,
    /// 指标查询表达式
    pub query: String,
    /// 告警条件
    pub condition: AlertCondition,
    /// 持续时间阈值
    pub duration: Duration,
    /// 告警级别
    pub severity: AlertSeverity,
    /// 标签
    pub labels: HashMap<String, String>,
    /// 注释
    pub annotations: HashMap<String, String>,
    /// 是否启用
    pub enabled: bool,
}

/// 告警条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AlertCondition {
    /// 大于阈值
    GreaterThan(f64),
    /// 小于阈值
    LessThan(f64),
    /// 等于
    EqualTo(f64),
    /// 不等于
    NotEqualTo(f64),
    /// 在范围内
    InRange(f64, f64),
    /// 不在范围内
    OutOfRange(f64, f64),
    /// 增长率
    GrowthRate(f64),
    /// 异常检测
    AnomalyDetection,
}

/// 告警级别
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum AlertSeverity {
    /// 信息
    Info,
    /// 警告
    Warning,
    /// 错误
    Error,
    /// 严重
    Critical,
}

/// 告警事件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlertEvent {
    /// 事件ID
    pub id: String,
    /// 规则ID
    pub rule_id: String,
    /// 告警名称
    pub name: String,
    /// 告警级别
    pub severity: AlertSeverity,
    /// 状态
    pub state: AlertState,
    /// 触发时间
    pub fired_at: SystemTime,
    /// 解决时间
    pub resolved_at: Option<SystemTime>,
    /// 当前值
    pub value: f64,
    /// 阈值
    pub threshold: f64,
    /// 标签
    pub labels: HashMap<String, String>,
    /// 注释
    pub annotations: HashMap<String, String>,
    /// 指纹
    pub fingerprint: String,
}

/// 告警状态
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AlertState {
    /// 待触发
    Pending,
    /// 已触发
    Firing,
    /// 已解决
    Resolved,
    /// 已抑制
    Suppressed,
}

/// 告警管理器
pub struct AlertManager {
    /// 告警规则
    rules: Arc<RwLock<HashMap<String, AlertRule>>>,
    /// 活跃告警
    active_alerts: Arc<RwLock<HashMap<String, AlertEvent>>>,
    /// 告警历史
    alert_history: Arc<RwLock<Vec<AlertEvent>>>,
    /// 通知器
    notifiers: Arc<RwLock<Vec<Arc<dyn AlertNotifier>>>>,
    /// 抑制规则
    inhibit_rules: Arc<RwLock<Vec<InhibitRule>>>,
    /// 分组规则
    group_rules: Arc<RwLock<Vec<GroupRule>>>,
    /// 配置
    config: AlertManagerConfig,
}

/// 告警管理器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlertManagerConfig {
    /// 评估间隔
    pub evaluation_interval: Duration,
    /// 最大告警历史
    pub max_alert_history: usize,
    /// 默认解决超时
    pub resolve_timeout: Duration,
    /// 分组等待时间
    pub group_wait: Duration,
    /// 分组间隔
    pub group_interval: Duration,
    /// 重复间隔
    pub repeat_interval: Duration,
}

impl Default for AlertManagerConfig {
    fn default() -> Self {
        Self {
            evaluation_interval: Duration::from_secs(15),
            max_alert_history: 10000,
            resolve_timeout: Duration::from_secs(300),
            group_wait: Duration::from_secs(10),
            group_interval: Duration::from_secs(10),
            repeat_interval: Duration::from_secs(3600),
        }
    }
}

/// 抑制规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InhibitRule {
    /// 源匹配器
    pub source_matchers: Vec<LabelMatcher>,
    /// 目标匹配器
    pub target_matchers: Vec<LabelMatcher>,
    /// 相等标签
    pub equal: Vec<String>,
}

/// 分组规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupRule {
    /// 分组标签
    pub group_by: Vec<String>,
    /// 匹配器
    pub matchers: Vec<LabelMatcher>,
}

/// 标签匹配器
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LabelMatcher {
    pub name: String,
    pub value: String,
    pub operator: MatchOperator,
}

/// 匹配操作符
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MatchOperator {
    Equal,
    NotEqual,
    Regex,
    NotRegex,
}

/// 告警通知器接口
#[async_trait]
pub trait AlertNotifier: Send + Sync {
    /// 发送告警通知
    async fn notify(&self, alerts: &[AlertEvent]) -> ServiceResult<()>;
    
    /// 通知器名称
    fn name(&self) -> &str;
    
    /// 是否健康
    async fn health_check(&self) -> ServiceResult<bool>;
}

impl AlertManager {
    /// 创建新的告警管理器
    pub fn new(config: AlertManagerConfig) -> Self {
        Self {
            rules: Arc::new(RwLock::new(HashMap::new())),
            active_alerts: Arc::new(RwLock::new(HashMap::new())),
            alert_history: Arc::new(RwLock::new(Vec::new())),
            notifiers: Arc::new(RwLock::new(Vec::new())),
            inhibit_rules: Arc::new(RwLock::new(Vec::new())),
            group_rules: Arc::new(RwLock::new(Vec::new())),
            config,
        }
    }

    /// 添加告警规则
    pub async fn add_rule(&self, rule: AlertRule) -> ServiceResult<()> {
        info!("Adding alert rule: {}", rule.name);
        self.rules.write().await.insert(rule.id.clone(), rule);
        Ok(())
    }

    /// 移除告警规则
    pub async fn remove_rule(&self, rule_id: &str) -> ServiceResult<bool> {
        let removed = self.rules.write().await.remove(rule_id).is_some();
        if removed {
            info!("Removed alert rule: {}", rule_id);
        }
        Ok(removed)
    }

    /// 添加通知器
    pub async fn add_notifier(&self, notifier: Arc<dyn AlertNotifier>) -> ServiceResult<()> {
        info!("Adding alert notifier: {}", notifier.name());
        self.notifiers.write().await.push(notifier);
        Ok(())
    }

    /// 评估指标并触发告警
    pub async fn evaluate_metrics(&self, metrics: &[MetricFamily]) -> ServiceResult<()> {
        let rules = self.rules.read().await;
        
        for rule in rules.values() {
            if !rule.enabled {
                continue;
            }

            // 评估规则
            if let Some(alert_event) = self.evaluate_rule(rule, metrics).await? {
                self.handle_alert_event(alert_event).await?;
            }
        }

        // 检查已解决的告警
        self.check_resolved_alerts().await?;
        
        Ok(())
    }

    /// 评估单个规则
    async fn evaluate_rule(&self, rule: &AlertRule, metrics: &[MetricFamily]) -> ServiceResult<Option<AlertEvent>> {
        // 简化的指标查询和评估逻辑
        for metric_family in metrics {
            if metric_family.name == rule.query {
                for metric in &metric_family.metrics {
                    let value = match &metric.value {
                        MetricValue::Counter(v) => *v,
                        MetricValue::Gauge(v) => *v,
                        MetricValue::Histogram { sum, .. } => *sum,
                        MetricValue::Summary { sum, .. } => *sum,
                    };

                    if self.evaluate_condition(&rule.condition, value) {
                        let fingerprint = self.generate_fingerprint(rule, &metric.labels);
                        
                        // 检查是否已存在
                        if !self.active_alerts.read().await.contains_key(&fingerprint) {
                            let alert_event = AlertEvent {
                                id: Uuid::new_v4().to_string(),
                                rule_id: rule.id.clone(),
                                name: rule.name.clone(),
                                severity: rule.severity.clone(),
                                state: AlertState::Firing,
                                fired_at: SystemTime::now(),
                                resolved_at: None,
                                value,
                                threshold: self.get_threshold(&rule.condition),
                                labels: metric.labels.clone(),
                                annotations: rule.annotations.clone(),
                                fingerprint: fingerprint.clone(),
                            };

                            return Ok(Some(alert_event));
                        }
                    }
                }
            }
        }

        Ok(None)
    }

    /// 评估告警条件
    fn evaluate_condition(&self, condition: &AlertCondition, value: f64) -> bool {
        match condition {
            AlertCondition::GreaterThan(threshold) => value > *threshold,
            AlertCondition::LessThan(threshold) => value < *threshold,
            AlertCondition::EqualTo(threshold) => (value - threshold).abs() < f64::EPSILON,
            AlertCondition::NotEqualTo(threshold) => (value - threshold).abs() >= f64::EPSILON,
            AlertCondition::InRange(min, max) => value >= *min && value <= *max,
            AlertCondition::OutOfRange(min, max) => value < *min || value > *max,
            AlertCondition::GrowthRate(_rate) => {
                // TODO: 实现增长率计算
                false
            }
            AlertCondition::AnomalyDetection => {
                // TODO: 实现异常检测
                false
            }
        }
    }

    /// 获取阈值
    fn get_threshold(&self, condition: &AlertCondition) -> f64 {
        match condition {
            AlertCondition::GreaterThan(v) => *v,
            AlertCondition::LessThan(v) => *v,
            AlertCondition::EqualTo(v) => *v,
            AlertCondition::NotEqualTo(v) => *v,
            AlertCondition::InRange(min, _) => *min,
            AlertCondition::OutOfRange(min, _) => *min,
            AlertCondition::GrowthRate(v) => *v,
            AlertCondition::AnomalyDetection => 0.0,
        }
    }

    /// 处理告警事件
    async fn handle_alert_event(&self, alert_event: AlertEvent) -> ServiceResult<()> {
        info!("Handling alert event: {}", alert_event.name);
        
        // 添加到活跃告警
        self.active_alerts.write().await.insert(alert_event.fingerprint.clone(), alert_event.clone());
        
        // 添加到历史
        let mut history = self.alert_history.write().await;
        history.push(alert_event.clone());
        
        // 保持历史大小
        if history.len() > self.config.max_alert_history {
            history.remove(0);
        }
        
        // 发送通知
        self.send_notifications(&[alert_event]).await?;
        
        Ok(())
    }

    /// 检查已解决的告警
    async fn check_resolved_alerts(&self) -> ServiceResult<()> {
        let mut resolved_alerts = Vec::new();
        let mut active_alerts = self.active_alerts.write().await;
        
        let now = SystemTime::now();
        active_alerts.retain(|_, alert| {
            if let Ok(duration) = now.duration_since(alert.fired_at) {
                if duration > self.config.resolve_timeout {
                    let mut resolved_alert = alert.clone();
                    resolved_alert.state = AlertState::Resolved;
                    resolved_alert.resolved_at = Some(now);
                    resolved_alerts.push(resolved_alert);
                    false
                } else {
                    true
                }
            } else {
                true
            }
        });
        
        if !resolved_alerts.is_empty() {
            info!("Resolved {} alerts", resolved_alerts.len());
            self.send_notifications(&resolved_alerts).await?;
        }
        
        Ok(())
    }

    /// 发送通知
    async fn send_notifications(&self, alerts: &[AlertEvent]) -> ServiceResult<()> {
        let notifiers = self.notifiers.read().await;
        
        for notifier in notifiers.iter() {
            if let Err(e) = notifier.notify(alerts).await {
                error!("Failed to send notification via {}: {}", notifier.name(), e);
            }
        }
        
        Ok(())
    }

    /// 生成告警指纹
    fn generate_fingerprint(&self, rule: &AlertRule, labels: &Labels) -> String {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};
        
        let mut hasher = DefaultHasher::new();
        rule.id.hash(&mut hasher);
        
        let mut sorted_labels: Vec<_> = labels.iter().collect();
        sorted_labels.sort_by_key(|(k, _)| *k);
        for (k, v) in sorted_labels {
            k.hash(&mut hasher);
            v.hash(&mut hasher);
        }
        
        format!("{:x}", hasher.finish())
    }

    /// 获取活跃告警
    pub async fn get_active_alerts(&self) -> Vec<AlertEvent> {
        self.active_alerts.read().await.values().cloned().collect()
    }

    /// 获取告警历史
    pub async fn get_alert_history(&self, limit: Option<usize>) -> Vec<AlertEvent> {
        let history = self.alert_history.read().await;
        match limit {
            Some(n) => history.iter().rev().take(n).cloned().collect(),
            None => history.clone(),
        }
    }

    /// 启动告警管理器
    pub async fn start(&self) -> ServiceResult<()> {
        info!("Starting alert manager");
        
        // TODO: 启动评估循环
        // TODO: 启动通知处理器
        // TODO: 启动Web API服务器
        
        Ok(())
    }

    /// 停止告警管理器
    pub async fn stop(&self) -> ServiceResult<()> {
        info!("Stopping alert manager");
        Ok(())
    }
}

/// 控制台通知器
pub struct ConsoleNotifier {
    name: String,
    colored: bool,
}

impl ConsoleNotifier {
    pub fn new(colored: bool) -> Self {
        Self {
            name: "console".to_string(),
            colored,
        }
    }
}

#[async_trait]
impl AlertNotifier for ConsoleNotifier {
    async fn notify(&self, alerts: &[AlertEvent]) -> ServiceResult<()> {
        for alert in alerts {
            let severity_str = match alert.severity {
                AlertSeverity::Info => if self.colored { "\x1b[32mINFO\x1b[0m" } else { "INFO" },
                AlertSeverity::Warning => if self.colored { "\x1b[33mWARNING\x1b[0m" } else { "WARNING" },
                AlertSeverity::Error => if self.colored { "\x1b[31mERROR\x1b[0m" } else { "ERROR" },
                AlertSeverity::Critical => if self.colored { "\x1b[35mCRITICAL\x1b[0m" } else { "CRITICAL" },
            };
            
            println!("[ALERT] {} - {} ({:?}): {} = {} (threshold: {})", 
                severity_str, 
                alert.name, 
                alert.state,
                alert.annotations.get("description").unwrap_or(&"No description".to_string()),
                alert.value, 
                alert.threshold
            );
        }
        Ok(())
    }

    fn name(&self) -> &str {
        &self.name
    }

    async fn health_check(&self) -> ServiceResult<bool> {
        Ok(true)
    }
}

/// Webhook 通知器
pub struct WebhookNotifier {
    name: String,
    url: String,
    client: reqwest::Client,
}

impl WebhookNotifier {
    pub fn new(name: String, url: String) -> Self {
        Self {
            name,
            url,
            client: reqwest::Client::new(),
        }
    }
}

#[async_trait]
impl AlertNotifier for WebhookNotifier {
    async fn notify(&self, alerts: &[AlertEvent]) -> ServiceResult<()> {
        let payload = serde_json::json!({
            "alerts": alerts,
            "groupKey": "default",
            "status": "firing",
            "receiver": "webhook",
            "groupLabels": {},
            "commonLabels": {},
            "commonAnnotations": {},
            "externalURL": "http://localhost:9093",
            "version": "1",
            "groupKey": format!("{}:{}", 
                SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
                alerts.len()
            )
        });

        let response = self.client
            .post(&self.url)
            .json(&payload)
            .send()
            .await
            .map_err(|e| ServiceError::AlertingError(format!("Webhook request failed: {}", e)))?;

        if !response.status().is_success() {
            return Err(ServiceError::AlertingError(
                format!("Webhook returned error status: {}", response.status())
            ));
        }

        debug!("Sent {} alerts to webhook {}", alerts.len(), self.url);
        Ok(())
    }

    fn name(&self) -> &str {
        &self.name
    }

    async fn health_check(&self) -> ServiceResult<bool> {
        match self.client.get(&self.url).send().await {
            Ok(response) => Ok(response.status().is_success()),
            Err(_) => Ok(false),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{MetricType, MetricFamily, Metric, MetricValue};
    use std::time::SystemTime;

    #[tokio::test]
    async fn test_alert_manager_basic() {
        let config = AlertManagerConfig::default();
        let manager = AlertManager::new(config);

        // 添加规则
        let rule = AlertRule {
            id: "test_rule".to_string(),
            name: "Test Rule".to_string(),
            query: "test_metric".to_string(),
            condition: AlertCondition::GreaterThan(100.0),
            duration: Duration::from_secs(60),
            severity: AlertSeverity::Warning,
            labels: HashMap::new(),
            annotations: HashMap::new(),
            enabled: true,
        };

        manager.add_rule(rule).await.unwrap();

        // 添加通知器
        let notifier = Arc::new(ConsoleNotifier::new(false));
        manager.add_notifier(notifier).await.unwrap();

        // 测试指标评估
        let metrics = vec![MetricFamily {
            name: "test_metric".to_string(),
            help: "Test metric".to_string(),
            metric_type: MetricType::Gauge,
            metrics: vec![Metric {
                name: "test_metric".to_string(),
                help: "Test metric".to_string(),
                metric_type: MetricType::Gauge,
                value: MetricValue::Gauge(150.0), // 超过阈值
                labels: HashMap::new(),
                timestamp: SystemTime::now(),
            }],
        }];

        manager.evaluate_metrics(&metrics).await.unwrap();

        // 检查活跃告警
        let alerts = manager.get_active_alerts().await;
        assert_eq!(alerts.len(), 1);
        assert_eq!(alerts[0].name, "Test Rule");
        assert_eq!(alerts[0].severity, AlertSeverity::Warning);
    }

    #[tokio::test]
    async fn test_alert_conditions() {
        let manager = AlertManager::new(AlertManagerConfig::default());

        // 测试不同条件
        assert!(manager.evaluate_condition(&AlertCondition::GreaterThan(10.0), 15.0));
        assert!(!manager.evaluate_condition(&AlertCondition::GreaterThan(10.0), 5.0));

        assert!(manager.evaluate_condition(&AlertCondition::LessThan(10.0), 5.0));
        assert!(!manager.evaluate_condition(&AlertCondition::LessThan(10.0), 15.0));

        assert!(manager.evaluate_condition(&AlertCondition::InRange(10.0, 20.0), 15.0));
        assert!(!manager.evaluate_condition(&AlertCondition::InRange(10.0, 20.0), 25.0));

        assert!(manager.evaluate_condition(&AlertCondition::OutOfRange(10.0, 20.0), 25.0));
        assert!(!manager.evaluate_condition(&AlertCondition::OutOfRange(10.0, 20.0), 15.0));
    }

    #[tokio::test]
    async fn test_webhook_notifier() {
        // 这个测试需要实际的webhook端点，在真实环境中测试
        let notifier = WebhookNotifier::new(
            "test_webhook".to_string(),
            "https://httpbin.org/post".to_string()
        );

        let alert = AlertEvent {
            id: "test_alert".to_string(),
            rule_id: "test_rule".to_string(),
            name: "Test Alert".to_string(),
            severity: AlertSeverity::Warning,
            state: AlertState::Firing,
            fired_at: SystemTime::now(),
            resolved_at: None,
            value: 150.0,
            threshold: 100.0,
            labels: HashMap::new(),
            annotations: HashMap::new(),
            fingerprint: "test_fingerprint".to_string(),
        };

        // 在有网络连接的环境中测试
        if let Ok(_) = notifier.notify(&[alert]).await {
            println!("Webhook notification sent successfully");
        }
    }
}